Imports System.IO

Public Class StreamReaderWriter
  Private _isDirty As Boolean

  Private Sub BrowseButton_Click( _
   ByVal sender As System.Object, _
   ByVal e As System.EventArgs) _
   Handles BrowseButton.Click

    With ofd
      .Filter = _
       "Text files (*.txt)|*.txt|" & _
       "All files (*.*)|*.*"

      If .ShowDialog() = Windows.Forms.DialogResult.OK Then
        ' Don't bother doing anything if the 
        ' user selects the same file as previously.
        ' If it's a new file, get the name and 
        ' clear the list.
        If .FileName <> FileNameLabel.Text Then
          FileNameLabel.Text = .FileName
          ContentsList.Items.Clear()
          _isDirty = False
        End If
      End If

      ' Enable the Fill button if a file was selected.
      FillButton.Enabled = (FileNameLabel.Text <> String.Empty)

      ' Enable the Save button if the file is "dirty".
      ' This could happen if you didn't 
      ' load a new file, but cancelled the File Open dialog box 
      ' or selected the same file as previously loaded.
      SaveButton.Enabled = _isDirty
    End With
  End Sub

  Private Sub StreamReaderWriter_Load( _
   ByVal sender As System.Object, _
   ByVal e As System.EventArgs) _
   Handles MyBase.Load

    ResetButtons(False)
  End Sub

  Private Sub FillButton_Click( _
   ByVal sender As System.Object, _
   ByVal e As System.EventArgs) _
   Handles FillButton.Click

    ' Fill the list and set up the 
    ' buttons correctly.
    FillList(ContentsList, FileNameLabel.Text)

    ResetButtons(True)
  End Sub

  Private Sub FillList( _
   ByVal lst As ListBox, _
   ByVal fileName As String)

    ' Fill a list box with the contents of the text file
    ' name provided, one line per item.

    ' Remove all existing items from the list box.
    lst.Items.Clear()
    ' Indicate that you don't want the list box to
    ' update its display until you call EndUpdate.
    lst.BeginUpdate()

    ' Any file interaction should include
    ' exception handling!
    Try
      Using fs As New FileStream(fileName, FileMode.Open)
        Using sr As New StreamReader(fs)

          ' =========================================
          ' If you want to retrieve a StreamReader
          ' from a FileInfo object, you can use code 
          ' like this:

          'Dim fi As New FileInfo("C:\TextFile.txt")

          ' Use the FileInfo object, fi, as necessary.

          ' Now open a StreamReader to retrieve the 
          ' contents of the file:
          'Dim sr As StreamReader = fi.OpenText()
          ' =========================================

          ' =========================================
          ' If you want to read the entire contents
          ' of the file at once, you can use
          ' code like this:
          '
          ' textInFile = sr.ReadToEnd()
          ' =========================================

          Dim textString As String
          Do
            textString = sr.ReadLine()
            If textString IsNot Nothing Then
              lst.Items.Add(textString)
            End If
          Loop Until (textString Is Nothing)
        End Using
      End Using

    Catch ex As Exception
      MessageBox.Show(ex.Message, "File Error")

    Finally
      ' Redraw the list box.
      lst.EndUpdate()
    End Try
  End Sub

  Private Sub ContentsList_SelectedIndexChanged( _
   ByVal sender As System.Object, _
   ByVal e As System.EventArgs) _
   Handles ContentsList.SelectedIndexChanged

    Dim selectedCount As Integer = ContentsList.SelectedIndices.Count

    ' If something is selected...
    If selectedCount > 0 Then
      ' Enable the up button unless you've selected
      ' the first row.
      UpButton.Enabled = (ContentsList.SelectedIndices.Item(0) > 0)
      ' Enable the down button unless you've selected
      ' the final row.
      DownButton.Enabled = _
      (ContentsList.SelectedIndices.Item(selectedCount - 1) < _
       ContentsList.Items.Count - 1)
    End If
  End Sub

  Private Sub UpButton_Click( _
   ByVal sender As System.Object, _
   ByVal e As System.EventArgs) _
   Handles UpButton.Click

    ' As soon as you move things around, 
    ' the selected indexes get lost. You 
    ' must copy the SelectedIndices array into
    ' a new array, so you can work with the items
    ' that were previously selected.
    Dim items(ContentsList.SelectedIndices.Count - 1) As Integer
    ContentsList.SelectedIndices.CopyTo(items, 0)

    ContentsList.BeginUpdate()
    ' Loop through each selected index
    For Each i As Integer In items
      SwapText(ContentsList, i, i - 1)
      SwapSelection(ContentsList, i, i - 1)
    Next
    ContentsList.EndUpdate()
    SaveButton.Enabled = True
    _isDirty = True
  End Sub

  Private Sub DownButton_Click( _
   ByVal sender As System.Object, _
   ByVal e As System.EventArgs) _
   Handles DownButton.Click

    ' As soon as you move things around, 
    ' the selected indexes get lost. You 
    ' must copy the SelectedIndices array into
    ' a new array, so you can work with the items
    ' that were previously selected.
    Dim items(ContentsList.SelectedIndices.Count - 1) As Integer
    ContentsList.SelectedIndices.CopyTo(items, 0)

    ContentsList.BeginUpdate()
    ' Loop backwards through each selected index
    ' You can't use a For Each loop to 
    ' loop backwards, so this code uses a 
    ' For ... Next loop instead.
    Dim i As Integer
    For index As Integer = items.Length - 1 To 0 Step -1
      i = items(index)
      SwapText(ContentsList, i, i + 1)
      SwapSelection(ContentsList, i, i + 1)
    Next
    ContentsList.EndUpdate()
    SaveButton.Enabled = True
  End Sub

  Private Sub SwapSelection( _
  ByVal lst As ListBox, _
  ByVal item1 As Integer, _
  ByVal item2 As Integer)
    ' Unselect the previously selected item,
    ' and select the new item.
    lst.SetSelected(item1, False)
    lst.SetSelected(item2, True)
  End Sub

  Private Sub SwapText( _
   ByVal lst As ListBox, _
   ByVal item1 As Integer, _
   ByVal item2 As Integer)

    ' Swap text in position item1 with text in item2
    Dim temp As String
    temp = lst.Items(item1).ToString()
    lst.Items(item1) = lst.Items(item2)
    lst.Items(item2) = temp
  End Sub

  Private Sub SaveButton_Click(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) Handles SaveButton.Click

    sfd.Filter = _
       "Text files (*.txt)|*.txt|" & _
       "All files (*.*)|*.*"
    sfd.OverwritePrompt = True
    sfd.AddExtension = True
    sfd.FileName = FileNameLabel.Text
    If sfd.ShowDialog() = Windows.Forms.DialogResult.OK Then
      SaveList(ContentsList, sfd.FileName)
      ResetButtons(True)
      ContentsList.ClearSelected()
    End If
  End Sub

  Private Sub SaveList( _
   ByVal lst As ListBox, _
   ByVal fileName As String)

    Try
      Using fs As New FileStream(fileName, FileMode.Create)
        Using sw As New StreamWriter(fs)
          For Each textString As String In lst.Items
            sw.WriteLine(textString)
          Next
        End Using
      End Using

    Catch ex As Exception
      MessageBox.Show(ex.Message, "File Error")
    End Try
  End Sub

  Private Sub ResetButtons(ByVal enableFill As Boolean)
    If Not enableFill Then
      ' If the parameter is set to 
      ' False, disable the Fill button.
      ' Otherwise, leave it alone.
      FillButton.Enabled = False
    End If
    SaveButton.Enabled = False
    UpButton.Enabled = False
    DownButton.Enabled = False
    _isDirty = False
  End Sub
End Class
